package proxy; /**
 * Copyright (C), 2015-2018, 北京译泰教育科技有限公司
 * FileName: dynamicProxy
 * Author:   andy
 * Date:     18/1/30 下午4:22
 * Description: ${DESCRIPTION}
 * History:
 */

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import sun.misc.ProxyGenerator;

/**
 * 〈一句话功能简述〉<br>
 *
 * @author andy
 * @version V1.0
 * @date 18/1/30 下午4:22
 */
public class DynamicProxy implements InvocationHandler {

    private Object target;

    public DynamicProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        Object result = method.invoke(target, args);
        after();
        return result;
    }

    private void before() {
        System.out.println("before：" + System.currentTimeMillis());
    }

    private void after() {
        System.out.println("after：" + System.currentTimeMillis());
    }

    public static void main(String[] args) {
        Hello hello = new HelloImpl();

        DynamicProxy dynamicProxy = new DynamicProxy(hello);
        Hello helloProxy = (Hello)Proxy.newProxyInstance(hello.getClass().getClassLoader(),
            hello.getClass().getInterfaces(), dynamicProxy);
        helloProxy.say();

        // 保存字节码
        createProxyClassFile();
    }


    private static void createProxyClassFile(){
        String name = "helloProxy";
        byte[] data = ProxyGenerator.generateProxyClass(name,new Class[]{Hello.class});
        FileOutputStream out =null;
        try {
            out = new FileOutputStream(name+".class");
            System.out.println((new File("hello")).getAbsolutePath());
            out.write(data);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(null!=out) try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
